using System;
using System.Collections.Generic;
using UnityEngine;

namespace IQIGame.Onigao.Framework
{
    [DisallowMultipleComponent]
    public partial class FrameworkEntry : MonoBehaviour
    {
        public static FrameworkEntry Instance { get; private set; }

        [SerializeField]
        private int m_FrameRate = 60;

        [SerializeField]
        private float m_GlobalTimeScale = 1;

        [SerializeField]
        private bool m_RunInBackground;

        [SerializeField]
        private bool m_DevMode;

        /// <summary>
        /// 游戏基准帧率
        /// </summary>
        public int FrameRate
        {
            get
            {
                return m_FrameRate;
            }
            set
            {
                Application.targetFrameRate = m_FrameRate = value;
            }
        }

        /// <summary>
        /// 全局时间缩放
        /// </summary>
        public float GlobalTimeScale
        {
            get
            {
                return m_GlobalTimeScale;
            }
            set
            {
                Time.timeScale = m_GlobalTimeScale = value;
            }
        }

        /// <summary>
        /// 获取或设置是否允许后台运行。
        /// </summary>
        public bool RunInBackground
        {
            get
            {
                return m_RunInBackground;
            }
            set
            {
                Application.runInBackground = m_RunInBackground = value;
            }
        }

        /// <summary>
        /// 开发模式
        /// </summary>
        public bool DevMode
        {
            get
            {
                return m_DevMode;
            }
            set
            {
                m_DevMode = value;
            }
        }

        private void Awake()
        {
            Instance = this;
        }

        /// <summary>
        /// 框架初始化
        /// 业务逻辑调用
        /// </summary>
        public void Init()
        {
            InitMgrRefs();
            InitAllModules();
            OnInit();
        }

        private void InitAllModules()
        {
            foreach (var kv in s_TypeMonoMap)
            {
                FrameMonoModule module = kv.Value;
                module.Init();
            }
        }

        private void OnInit()
        {
            MonoDriver.onApplicationQuitEvent += OnAppQuit;
            Application.lowMemory += OnLowMemory;
            ProcedureFSM.Instance.ActivateUpdate();
            Application.targetFrameRate = m_FrameRate;
#if UNITY_EDITOR
            Application.runInBackground = m_RunInBackground;
#elif UNITY_STANDALONE_WIN
            Application.runInBackground = true;
#else
            Application.runInBackground = false;
#endif
            GlobalTimeScale = 1;
        }

        public void EnterGame()
        {
            foreach (var kv in s_TypeMonoMap)
            {
                FrameMonoModule module = kv.Value;
                module.EnterGame();
            }
        }

        /// <summary>
        /// 应用程序退出
        /// </summary>
        private void OnAppQuit()
        {
            MonoDriver.onApplicationQuitEvent -= OnAppQuit;

        }

        private void OnDestroy()
        {
            Application.lowMemory -= OnLowMemory;
            Shutdown();
        }

        private void OnLowMemory()
        {
            FrameworkEntry.ObjectPoolMgr.ForceReleaseAll();
            ClassPool.ClearAll();
            PODPool.ClearAll();
            ConcurrentClassPool.ClearAll();
            System.GC.Collect();
            Resources.UnloadUnusedAssets();
        }

        private void Shutdown()
        {
            foreach (var kv in s_TypeMonoMap)
            {
                kv.Value.Shutdown();
            }
        }
    }
}
